#include "NetManager.h"
#include "spdlog/spdlog.h"
#include "NetPeer.h"
#include "NetPacket.h"
#include "NetPacketPool.h"
#include "NetConnectRequestPacket.h"
#include "NetUtils.h"
#include "NetDebug.h"

namespace LiteNetLib
{
    NetManager::NetManager(INetEventListener *listener) : m_udp_socket(m_io_context), m_netEventListener(listener) {}

    NetManager::~NetManager()
    {
        stop();
        NetEvent *nextNetEvent = m_netEventPoolHead;
        while(nextNetEvent != nullptr)
        {
            nextNetEvent = m_netEventPoolHead->nextNetEvent;
            delete m_netEventPoolHead;
            m_netEventPoolHead = nextNetEvent;
        }
    }

    void NetManager::updateLogic()
    {
        auto lastTime = std::chrono::steady_clock::now();
        while (m_udp_socket.is_open())
        {
            auto msPerTick = std::chrono::milliseconds(updateTime);
            auto nowTime = std::chrono::steady_clock::now();
            auto msec = std::chrono::duration_cast<std::chrono::milliseconds>(nowTime - lastTime).count();
            
            pollUpdate(msec);

            // ****************************************************************
            // 计算时间差，并进行休眠
            // ****************************************************************
            auto tickTime = std::chrono::steady_clock::now() - nowTime;
            if (tickTime < msPerTick)
            {
                std::this_thread::sleep_for(msPerTick - tickTime);
            }
            lastTime = nowTime;
        }
    }


    void NetManager::addPeer(NetPeerPtr peer)
    {
        m_peersMapMutex.lock();
        m_peersMap[peer->getHashCode()] = peer;
        m_peersMapMutex.unlock();
    }

    void NetManager::removePeer(NetPeerPtr peer)
    {
        m_peersMapMutex.lock();
        auto it = m_peersMap.find(peer->getHashCode());
        if (it != m_peersMap.end())
        {
            m_peersMap.erase(it);
        }
        m_peersMapMutex.unlock();
    }

    void NetManager::disconnectPeerForce(NetPeerPtr peer, DisconnectReason reason, NetPacket *packet)
    {
        disconnectPeer(peer, reason, true, nullptr, 0, packet);
    }

    void NetManager::disconnectPeer(NetPeerPtr peer, DisconnectReason reason, bool force, const char *disconnectData, uint32_t dataLength, NetPacket *eventData)
    {
        ShutdownResult shutdownResult = peer->shutdown(disconnectData, dataLength, force);
        if (shutdownResult == ShutdownResult::None)
        {
            return;
        }
        createEvent(NetEventType::Disconnect, peer, nullptr, reason, nullptr, DeliveryMethod::Unreliable, eventData);
    }

    void NetManager::createEvent(NetEventType type, NetPeerPtr peer, net_endpoint *endpoint, DisconnectReason disconnectReason, ConnectionRequest *connectionRequest, DeliveryMethod deliveryMethod, NetPacket *readerSource)
    {
        NetEvent *netEvent = nullptr;
        bool unsyncEvent = unsyncedEvents;

        // 行为池中取出对象
        m_netEventPoolMutex.lock();
        netEvent = m_netEventPoolHead;
        if (netEvent == nullptr)
        {
            netEvent = new NetEvent(this);
        }
        else
        {
            m_netEventPoolHead = netEvent->nextNetEvent;
        }
        m_netEventPoolMutex.unlock();

        netEvent->manualRecycle = false;
        netEvent->type = type;
        netEvent->headerSize = (readerSource != nullptr ? readerSource->getHeaderSize() : 0);
        netEvent->packet = readerSource;
        netEvent->peer = peer;
        if (endpoint != nullptr)
        {
            netEvent->endpoint = *endpoint;
        }
        netEvent->disconnectReason = disconnectReason;
        netEvent->connectionRequest = connectionRequest;
        netEvent->deliveryMethod = deliveryMethod;

        if (unsyncEvent)
        {
            processEvent(netEvent);
        }
        else
        {
            m_netEventsQueue.push(netEvent);
        }
    }

    void NetManager::processEvent(NetEvent *netEvent)
    {
        // NetDebug::Info("[NM] Processing event: {}", (uint8_t)netEvent->type);

        uint16_t headerSize = 0;
        uint32_t packetSize = 0;
        if (netEvent->packet != nullptr)
        {
            headerSize = netEvent->headerSize; //netEvent->packet->getHeaderSize();
            packetSize = netEvent->packet->getPacketSize();
        }

        switch (netEvent->type)
        {
        case NetEventType::Connect:
            m_netEventListener->OnPeerConnected(netEvent->peer);
            break;
        case NetEventType::Disconnect:
            if (netEvent->packet == nullptr)
            {
                m_netEventListener->OnPeerDisconnected(netEvent->peer, netEvent->disconnectReason, nullptr, 0);
            }
            else
            {
                m_netEventListener->OnPeerDisconnected(netEvent->peer, netEvent->disconnectReason, &(netEvent->packet->getRawData()[headerSize]), packetSize - headerSize);
            }
            break;
        case NetEventType::Receive:
            if (netEvent->packet != nullptr)
            {
                m_netEventListener->OnNetworkReceive(netEvent->peer, &(netEvent->packet->getRawData()[headerSize]), (packetSize - headerSize), netEvent->deliveryMethod);
            }
            else
            {
                NetDebug::Error("[NetEventType::Receive] no data");
            }
            break;
        case NetEventType::ReceiveUnconnected:
            if (netEvent->packet != nullptr)
            {
                m_netEventListener->OnNetworkReceiveUnconnected(&(netEvent->endpoint), &(netEvent->packet->getRawData()[headerSize]), (packetSize - headerSize), UnconnectedMessageType::BasicMessage);
            }
            else
            {
                NetDebug::Error("[NetEventType::ReceiveUnconnected] no data");
            }
            break;
        case NetEventType::Broadcast:
            m_netEventListener->OnNetworkReceiveUnconnected(&(netEvent->endpoint), &(netEvent->packet->getRawData()[headerSize]), (packetSize - headerSize), UnconnectedMessageType::Broadcast);
            break;
        case NetEventType::Error:
            break;
        case NetEventType::ConnectionLatencyUpdated:
            break;
        case NetEventType::ConnectionRequest:
            m_netEventListener->OnConnectionRequest(netEvent->connectionRequest);
            break;
        case NetEventType::MessageDelivered:
            break;
        }
        if (netEvent->manualRecycle == false)
        {
            recycleEvent(netEvent);
        }
    }

    void NetManager::recycleEvent(NetEvent *netEvent)
    {
        netEvent->connectionRequest = nullptr;
        if (netEvent->packet != nullptr)
        {
            NetPacketPool::GetInstance().recycleOrDelete(netEvent->packet);
            netEvent->packet = nullptr;
        }
        netEvent->peer = nullptr;
        
        m_netEventPoolMutex.lock();
        netEvent->nextNetEvent = m_netEventPoolHead;
        m_netEventPoolHead = netEvent;
        m_netEventPoolMutex.unlock();
    }

    void NetManager::pollUpdate(uint32_t dt)
    {
        m_clearPackageCountTime += dt;
        if (m_clearPackageCountTime >= 1000)
        {
            m_clearPackageCountTime -= 1000;
            m_limitPackageMapMutex.lock();
            for (auto &pair : m_limitPackageMap)
            {
                if (pair.second >= NetConstants::secondClearPackageCount)
                {
                    pair.second -= NetConstants::secondClearPackageCount;
                }
                else
                {
                    pair.second = 0;
                }
            }
            m_limitPackageMapMutex.unlock();
        }

        m_clearBanTime += dt;
        if (m_clearBanTime >= NetConstants::secondClearBan)
        {
            m_clearBanTime -= NetConstants::secondClearBan;
            m_banIpMutex.lock();
            m_banIpSet.clear();
            m_banIpMutex.unlock();
        }


        std::vector<size_t> peersToRemove;
        std::vector<std::string> mapIpToRemove;

        m_peersMapMutex.lock();

        // ****************************************************************
        // 遍历客户端，并找出要移除的对象
        // ****************************************************************
        for (auto it = m_peersMap.begin(); it != m_peersMap.end(); ++it)
        {
            if(it->second->getConnectionState() == ConnectionState::Disconnected || it->second->getTimeSinceLastPacket() > disconnectTimeout)
            {
                peersToRemove.push_back(it->first);
                mapIpToRemove.push_back(NetUtils::GetSockIP(it->second->getEndpoint()));
            }
            else
            {
                it->second->update(dt);
            }
        }

        // ****************************************************************
        // 移除客户端
        // ****************************************************************
        if (peersToRemove.size() > 0)
        {
            for (size_t addressHashCode : peersToRemove)
            {
                auto it = m_peersMap.find(addressHashCode);
                if (it != m_peersMap.end())
                {
                    m_peersMap.erase(it);
                }
            }
            peersToRemove.clear();
        }
        m_peersMapMutex.unlock();




        m_limitPackageMapMutex.lock();
        for (const std::string & sockIP : mapIpToRemove)
        {
            auto it = m_limitPackageMap.find(sockIP);
            if (it != m_limitPackageMap.end())
            {
                m_limitPackageMap.erase(it);
            }
        }
        m_limitPackageMapMutex.unlock();
    }
    

    void NetManager::pollEvents()
    {
        NetEvent *event;
        while(m_netEventsQueue.try_pop(event))
        {
            processEvent(event);
        }
    }



    NetPeerPtr NetManager::onConnectionSolved(ConnectionRequest *request, const char *rejectData, uint32_t rejectDataLength)
    {
        NetPeerPtr netPeer = nullptr;
        size_t requsetHashCode = NetUtils::SockHashCode(&(request->endpoint));
        if (request->result == ConnectionRequestResult::RejectForce)
        {
            NetDebug::Info("[NM] Peer connect reject force.");
            if (rejectData != nullptr && rejectDataLength > 0)
            {
                NetPacket *shutdownPacket = NetPacketPool::GetInstance().getWithProperty(PacketProperty::Disconnect, rejectDataLength);
                shutdownPacket->setConnectionNumber(request->connectionNumber);
                NetUtils::Int64ToByte(&(shutdownPacket->getRawData()[1]), request->connectionTime);
                if (shutdownPacket->getPacketSize() >= NetConstants::PossibleMtu[0])
                {
                    NetDebug::Error("[Peer] Disconnect additional data size more than MTU!");
                }
                else
                {
                    memcpy(&(shutdownPacket->getRawData()[9]), rejectData, rejectDataLength);
                }
                sendNetPacketAndRecycle(shutdownPacket, &(request->endpoint));
            }
        }
        else
        {
            std::unique_lock<std::mutex> lk(m_peersMapMutex, std::adopt_lock);

            auto it = m_peersMap.find(requsetHashCode);
            if (it != m_peersMap.end())
            {
                netPeer = it->second;
                lk.unlock();
            }
            else if (request->result == ConnectionRequestResult::Reject)
            {
                netPeer = NetPeerPtr(new NetPeer(this, &(request->endpoint)));
                netPeer->reject(request->connectionTime, request->connectionNumber, rejectData, rejectDataLength);
                addPeer(netPeer);
                lk.unlock();
                NetDebug::Info("[NM] Peer connect reject.");
            }
            else
            {
                netPeer = NetPeerPtr(new NetPeer(this, &(request->endpoint), request->connectionTime, request->connectionNumber));
                addPeer(netPeer);
                lk.unlock();
                createEvent(NetEventType::Connect, netPeer, nullptr, DisconnectReason::ConnectionFailed, nullptr, DeliveryMethod::Unreliable, nullptr);
                NetDebug::Info("[NM] Received peer connection Id: {}, EP: {}", netPeer->getConnectTime(), netPeer->getAddress());
            }
        }

        m_requestMapMutex.lock();
        auto it = m_requestMap.find(requsetHashCode);
        if (it != m_requestMap.end())
        {
            delete it->second;
            m_requestMap.erase(it);
        }
        m_requestMapMutex.unlock();

        return netPeer;
    }
    
    // 接收udp服务收到的消息
    // void NetManager::onReceiveMessage(asio::error_code ec, size_t bytes_recvd)
    // {
    //     if (!ec && bytes_recvd > 0)
    //     {
    //         try
    //         {
    //             dataReceived(m_recv_buffer, bytes_recvd, &m_remote_endpoint);
    //         }
    //         catch(const std::exception& e)
    //         {
    //             NetDebug::Error("[NM] SocketReceiveThread error: {}", e.what());
    //         }
    //     }
    // }

    // 收到数据包
    void NetManager::dataReceived(char *dataBuff, uint32_t dataSize, net_endpoint* sockPtr)
    {
        if (false == NetPacket::Verify(dataBuff, dataSize))
        {
            NetDebug::Error("[NM] DataReceived: bad!, data size : {}, data: {}", dataSize, NetUtils::ToHexString(dataBuff, dataSize > 32 ? 32 : dataSize));
            return;
        }
        switch (NetPacket::GetProperty(dataBuff))
        {
        case PacketProperty::ConnectRequest:
            if (NetConnectRequestPacket::GetProtocolId(dataBuff) != NetConstants::ProtocolId)
            {
                sendNetPacketAndRecycle(NetPacketPool::GetInstance().getWithProperty(PacketProperty::InvalidProtocol), sockPtr);
                return;
            }
            break;
        case PacketProperty::Broadcast:
            if (broadcastReceiveEnabled)
            {
                NetPacket *netPacket = NetPacketPool::GetInstance().getPacket(dataSize);
                memcpy(netPacket->getRawData(), dataBuff, dataSize);
                createEvent(NetEventType::Broadcast, nullptr, sockPtr, DisconnectReason::ConnectionFailed, nullptr, DeliveryMethod::Unreliable, netPacket);
            }
            return;
        case PacketProperty::UnconnectedMessage:
            if (unconnectedMessagesEnabled)
            {
                NetPacket *netPacket = NetPacketPool::GetInstance().getPacket(dataSize);
                memcpy(netPacket->getRawData(), dataBuff, dataSize);
                createEvent(NetEventType::ReceiveUnconnected, nullptr, sockPtr, DisconnectReason::ConnectionFailed, nullptr, DeliveryMethod::Unreliable, netPacket);
            }
            return;
        case PacketProperty::NatMessage:
            return;
        }

        // 查找对应的连接对象
        NetPeerPtr netPeer = nullptr;
        size_t addressHashCode = NetUtils::SockHashCode(sockPtr);
        m_peersMapMutex.lock();
        auto it = m_peersMap.find(addressHashCode);
        if (it != m_peersMap.end())
        {
            netPeer = it->second;
        }
        m_peersMapMutex.unlock();


        switch (NetPacket::GetProperty(dataBuff))
        {
        case PacketProperty::ConnectRequest:
            {
                NetPacket *netPacket = NetPacketPool::GetInstance().getPacket(dataSize);
                memcpy(netPacket->getRawData(), dataBuff, dataSize);
                NetConnectRequestPacket *connRequest = NetConnectRequestPacket::FromData(netPacket, sockPtr);
                if (connRequest != nullptr)
                {
                    processConnectRequest(sockPtr, netPeer, connRequest);
                    delete connRequest;
                }
            }
            break;
        case PacketProperty::PeerNotFound:
            if (netPeer != nullptr)
            {
                if (netPeer->getConnectionState() != ConnectionState::Connected)
                {
                    return;
                }
                if (dataSize == 1)
                {
                    NetPacket *p = NetPacketPool::GetInstance().getWithProperty(PacketProperty::PeerNotFound, 9);
                    p->getRawData()[1] = 0;
                    NetUtils::Int64ToByte(&(p->getRawData()[2]), netPeer->getConnectTime());
                    sendNetPacketAndRecycle(p, sockPtr);
                    // NetDebug::Info("PeerNotFound sending connectTime: {}", netPeer->getConnectTime());
                }
                else if (dataSize == 10 && dataBuff[1] == 0)
                {
                    // NetDebug::Info("PeerNotFound received our connectTime: {}", netPeer->getConnectTime());
                    disconnectPeerForce(netPeer, DisconnectReason::RemoteConnectionClose, nullptr);
                }
            }
            else
            {
                dataBuff[1] = 1;
                sendRaw(dataBuff, dataSize, sockPtr);
            }
            break;
        case PacketProperty::InvalidProtocol:
            if (netPeer != nullptr && netPeer->getConnectionState() == ConnectionState::Outgoing)
            {
                disconnectPeerForce(netPeer, DisconnectReason::InvalidProtocol, nullptr);
            }
            break;
        case PacketProperty::Disconnect:
            if (netPeer != nullptr)
            {
                DisconnectResult result = netPeer->processDisconnect(dataBuff, dataSize);
                if (result == DisconnectResult::None)
                {
                    return;
                }
                NetPacket *netPacket = NetPacketPool::GetInstance().getPacket(dataSize);
                memcpy(netPacket->getRawData(), dataBuff, dataSize);
                disconnectPeerForce(netPeer, (result == DisconnectResult::Disconnect ? DisconnectReason::RemoteConnectionClose : DisconnectReason::ConnectionRejected), netPacket);
            }
            sendNetPacketAndRecycle(NetPacketPool::GetInstance().getWithProperty(PacketProperty::ShutdownOk), sockPtr);
            break;
        case PacketProperty::ConnectAccept:
            break;
        default:
            if (netPeer != nullptr)
            {
                netPeer->processData(dataBuff, dataSize);
            }
            else
            {
                NetDebug::Debug("{} 找不到NetPeer", addressHashCode);
                // sendNetPacketAndRecycle(NetPacketPool::GetInstance().getWithProperty(PacketProperty::PeerNotFound), sockPtr);
            }
            break;
        }
    }

    void NetManager::createReceiveEvent(NetPacket *packet, DeliveryMethod method, int32_t headerSize, NetPeerPtr fromPeer)
    {
        // NetDebug::Info("[{}][{}][{}]fromPeer receive event", fromPeer->getAddress(), NetUtils::GetSockIP(fromPeer->getEndpoint()), fromPeer->getHashCode());

        NetEvent *netEvent = nullptr;
        m_netEventPoolMutex.lock();
        netEvent = m_netEventPoolHead;
        if (netEvent == nullptr)
        {
            netEvent = new NetEvent(this);
        }
        else
        {
            m_netEventPoolHead = netEvent->nextNetEvent;
        }
        m_netEventPoolMutex.unlock();

        netEvent->type = NetEventType::Receive;
        netEvent->packet = packet;

        // // 这是故意留下的bug，用于出错时查找堆栈的
        // if (packet->getProperty() > PacketProperty::Empty)
        // {
        //     netEvent->packet = nullptr;
        //     netEvent->packet->getRawData()[0x00] = 0xAA;
        // }
        netEvent->headerSize = headerSize;
        netEvent->peer = fromPeer;

        netEvent->endpoint = *(fromPeer->getEndpoint());

        netEvent->deliveryMethod = method;

        if (unsyncedConnectAndDisconnectEvent && (netEvent->type == NetEventType::Connect || netEvent->type == NetEventType::Disconnect))
        {
            processEvent(netEvent);
        }
        else if (unsyncedReceiveEvent && netEvent->type == NetEventType::Receive)
        {
            processEvent(netEvent);
        }
        else if (unsyncedEvents)
        {
            processEvent(netEvent);
        }
        else
        {
            m_netEventsQueue.push(netEvent);
        }
    }

    // 处理连接请求
    void NetManager::processConnectRequest(net_endpoint *sockPtr, NetPeerPtr peer, NetConnectRequestPacket *connRequest)
    {
        uint8_t connectionNumber = connRequest->connectionNumber;
        ConnectionRequest *req = nullptr;

        if (peer != nullptr)
        {
            ConnectRequestResult processResult = peer->processConnectRequest(connRequest);
            switch (processResult)
            {
            case ConnectRequestResult::Reconnection:
                disconnectPeerForce(peer, DisconnectReason::Reconnect, nullptr);
                removePeer(peer);
                break;
            case ConnectRequestResult::NewConnection:
                removePeer(peer);
                break;
            case ConnectRequestResult::P2PLose:
                disconnectPeerForce(peer, DisconnectReason::PeerToPeerConnection, nullptr);
                removePeer(peer);
                break;
            default:
                return;
            }
            if (processResult != ConnectRequestResult::P2PLose)
            {
                connectionNumber = (uint8_t)((peer->getConnectionNum() + 1) % NetConstants::MaxConnectionNumber);
            }
        }

        {
            size_t addressHashCode = NetUtils::SockHashCode(sockPtr);
            std::lock_guard<std::mutex> lk(m_requestMapMutex);
            auto it = m_requestMap.find(addressHashCode);
            if(it != m_requestMap.end())
            {
                it->second->updateRequest(connRequest);
                return;
            }
            req = new ConnectionRequest(connRequest->connectionTime, connectionNumber, connRequest->netDataReader, sockPtr, this);
            m_requestMap[addressHashCode] = req;
            
            // 防止数据包被回收处理
            connRequest->netDataReader.netPacket = nullptr;
        }
        createEvent(NetEventType::ConnectionRequest, nullptr, sockPtr, DisconnectReason::ConnectionFailed, req, DeliveryMethod::Unreliable, nullptr);
    }
    /******************************************************************************************************************************************/





    /***********************************************************************************************************
     * @brief 向特定的 ip 发送数据包，但是不会回收数据包，数据包要自行处理
     * @param packet 数据包
     * @param sockPtr ip 地址
    ************************************************************************************************************/
    void NetManager::sendNetPacket(NetPacket *packet, net_endpoint *sockPtr)
    {
        sendRaw(packet->getRawData(), packet->getPacketSize(), sockPtr);
    }

    /***********************************************************************************************************
     * @brief 向特定的 ip 发送数据包，并回收数据包
     * @param packet 数据包
     * @param sockPtr ip 地址
    ************************************************************************************************************/
    void NetManager::sendNetPacketAndRecycle(NetPacket *packet, net_endpoint* sockPtr)
    {
        sendRaw(packet->getRawData(), packet->getPacketSize(), sockPtr);
        NetPacketPool::GetInstance().recycleOrDelete(packet);
    }

    /***********************************************************************************************************
     * @brief 创建udp服务
     * @param host 绑定ip地址，0.0.0.0 为ipv4地址, :: 为ipv6地址
     * @param port 网络端口
     * @return true-开启成功，false-开启失败
    ***********************************************************************************************************/
    bool NetManager::start(const char* host, uint16_t port, bool useInternalThread)
    {
        m_useInternalThread = useInternalThread;

        asio::ip::address ip_address = asio::ip::make_address(host);
        if (ip_address.is_v4() == false && ip_address.is_v6() == false)
        {
            return false;
        }

        try
        {
            net_endpoint endpoint(ip_address, port);
            m_udp_socket.open(endpoint.protocol());
            m_udp_socket.bind(endpoint);
            if (m_udp_socket.is_open() == false)
            {
                NetDebug::Error("socket create error");
                return false;
            }
        }
        catch(const std::exception& e)
        {
            NetDebug::Error("failed to bind port : {}, exception message: {}", port, e.what());
            return false;
        }

        m_recvDataThread = new std::thread([this]
        {
            while(m_udp_socket.is_open())
            {
                try
                {
                    size_t length = m_udp_socket.receive_from(asio::buffer(m_recv_buffer, sizeof(m_recv_buffer)), m_remote_endpoint);
                    if (length > 0)
                    {
                        std::string ip = NetUtils::GetSockIP(&m_remote_endpoint);
                        bool isBan = false;

                        m_banIpMutex.lock();
                        if (m_banIpSet.find(ip) != m_banIpSet.end())
                        {
                            isBan = true;
                        }
                        m_banIpMutex.unlock();

                        if (isBan == false)
                        {
                            bool needBan = false;
                            m_limitPackageMapMutex.lock();
                            auto it = m_limitPackageMap.find(ip);
                            if (it != m_limitPackageMap.end())
                            {
                                it->second++;
                                if (it->second >= NetConstants::banIpLimitPackageCount)
                                {
                                    needBan = true;
                                }
                            }
                            else
                            {
                                m_limitPackageMap[ip] = 1;
                            }
                            m_limitPackageMapMutex.unlock();

                            // 临时封禁
                            if (needBan)
                            {
                                fmt::print(fmt::format("[LiteNetLib] ip : {} 每秒数据包发送过多，已经临时封禁\n", NetUtils::GetAddressStr(&m_remote_endpoint)));
                                m_banIpMutex.lock();
                                m_banIpSet.insert(ip);
                                m_banIpMutex.unlock();
                            }
                            else
                            {
                                dataReceived(m_recv_buffer, length, &m_remote_endpoint);
                            }
                        }
                    }
                }
                catch(const std::exception& e)
                {
                    NetDebug::Error("[NM] SocketReceiveThread error: {}", std::string(e.what()));
                }
                catch(...)
                {
                    NetDebug::Error("[LiteNetLib] 发生未知异常");
                    
                    fmt::print("[LiteNetLib] 发生未知异常\n");
                }
            }
        });

        // 绑定消息接收函数
        // m_udp_socket.async_receive_from(
        //     asio::buffer(m_recv_buffer, sizeof(m_recv_buffer)), 
        //     m_remote_endpoint, 
        //     std::bind(&NetManager::onReceiveMessage, this, std::placeholders::_1, std::placeholders::_2)
        // );

        if (m_useInternalThread)
        {
            m_logicThread = new std::thread(std::bind(&NetManager::updateLogic, this));
        }
        return true;
    }

    void NetManager::sendRaw(const char* buff, uint32_t buffSize, net_endpoint *endpoint)
    {
        // 阻塞发送
        m_udp_socket.send_to(asio::buffer(buff, buffSize), *endpoint);

        // 异步发送
        /*
        m_udp_socket.async_send_to(asio::buffer(buff, buffSize),sockPtr->endpoint,
            [](const asio::error_code& error, std::size_t bytes_transferred) {
                if (!error) {
                    std::cout << "Sent " << bytes_transferred << " bytes" << std::endl;
                } else {
                    std::cerr << "Send error: " << error.message() << std::endl;
                }
            });
        */
    }


    /***********************************************************************************************************
     * @brief 判断 udp 服务是否还在运行中
    ***********************************************************************************************************/
    bool NetManager::isRunning()
    {
        return m_udp_socket.is_open();
    }


    /***********************************************************************************************************
     * @brief 关闭 udp 服务
     * @note 关闭服务后，不会触发客户端关闭事件
    ***********************************************************************************************************/
    void NetManager::stop()
    {
        if (m_udp_socket.is_open())
        {
            m_udp_socket.close();
        }

        if (m_recvDataThread != nullptr)
        {
            m_recvDataThread->join();
            delete m_recvDataThread;
        }

        if (m_logicThread != nullptr)
        {
            m_logicThread->join();
            delete m_logicThread;
        }
        m_peersMapMutex.lock();
        m_peersMap.clear();
        m_peersMapMutex.unlock();
    }

}
